using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Be.Timvw.Framework.Domain.Specifications
{
    /// <summary>
    /// Specifications for the OrSpecification.
    /// </summary>
    [TestClass]
    public class WhenTestingSatisfactionOfSpecificationOrSpecification
    {
        /// <summary>
        /// Should not be satisifed when none of the specifications are satisfied.
        /// </summary>
        [TestMethod]
        public void ShouldNotBeSatisfiedWhenNoneOfTheSpecificationsAreSatisfied()
        {
            ISpecification<int> specification = new OrSpecification<int>(new ISpecification<int>[]
            {
                new FalseSpecification<int>(),
                new FalseSpecification<int>()
            });

            Assert.IsFalse(specification.IsSatisfiedBy(0));
        }

        /// <summary>
        /// Should be satisfied as soon as a specification is satisified.
        /// </summary>
        [TestMethod]
        public void ShouldBeSatisfiedWhenAtLeastOneSpecificationIsSatisfied()
        {
            ISpecification<int> specification = new OrSpecification<int>(new ISpecification<int>[]
            {
                new FalseSpecification<int>(),
                new TrueSpecification<int>()
            });

            Assert.IsTrue(specification.IsSatisfiedBy(0));
        }

        /// <summary>
        /// Should stop evaluating as soon as one specification is satisfied.
        /// </summary>
        [TestMethod]
        public void ShouldStopEvaluatingAsSoonAsOneSpecificationIsSatisfied()
        {
            // if the second specification is evaluated, it throws.
            ISpecification<string> specification = new OrSpecification<string>(new ISpecification<string>[]
            {
                new TrueSpecification<string>(),
                new MoreThanThenCharactersSpecification()
            });

            Assert.IsTrue(specification.IsSatisfiedBy(null));
        }
    }
}